
**********************************************
*                                            *
*  A simple way of switching the CPU in FRM, *
*   featuring up to 4Gb of linear memory !   *
* (c)oderight LCA/Infiny and Jedi/Sector One *
*                                            *
**********************************************

* Set the CPU in Flat-Real-Mode : enjoy 4Gb of linear memory !

initFRM pusha.l
        pushf

	smsw a
	test.b #1,a
	beq okay

        move cs,d
        move d,ds
        move #lame,d
        move.b #9,ah
        trap #$21
        move #$4cff,a
        trap #$21

lame    dc.b "Hey ! This program is good enough to manage its memory itself."
        dc.b 13,10
        dc.b "Please remove your memory manager (EMM, QEMM...) and try again."
        dc.b 13,10,'$'

!ptrCode        set 8
!ptrData        set 16
!cSizeGDT       set 24

okay    move ds,d
        move cs,a
        move a,ds
        move a,currentSeg

        movezx.l ax,ae
        shl.l #4,a
        move.l a,b
        lea segmentGDT,si

        move a,!ptrCode+2(si)
        move a,!ptrData+2(si)

        ror.l #16,a
        move.b a,!ptrCode+4(si)
        move.b a,!ptrData+4(si)

        move.b #0,!ptrCode+7(si)
        move.b #0,!ptrData+7(si)

        xor.l a,a
        move si,a
        add.l a,b
        move #!cSizeGDT,pointerGDT
        move.l b,pointerGDT+2

        intoff
        in.b #$70,a
        cs:move.b a,saveNMI+1
        or.b #$80,a
        out.b a,$70

        lgdt pointerGDT

        move ss,b
        move es,c

        move.l cr0,a
        or.b #1,a
        move.l a,cr0

        dc.b $66,$ea
        dc.w pMode,0
        dc.w !ptrCode

pMode   move #!ptrData,a
        move a,ds
        move a,es
        move a,fs
        move a,gs
        move a,ss

        move.l cr0,a
        and.b #254,a
        move.l a,cr0

        dc.b $66,$ea
        dc.w rMode,0
currentSeg
        dc.w 0

rMode   move b,ss
        move d,ds
        move c,es

        xor a,a
        move a,fs
        move a,gs

saveNMI move.b #$12,a
        out.b a,$70
        inton

        popf
        popa.l
        rts

        align.l

pointerGDT
        ds.l 2

segmentGDT
        ds.w 4
        dc.w $ffff,0
        dc.b 0,$9a
        dc.w $9f
        dc.w $ffff,0
        dc.b 0,$92
        dc.w $9f
